
#include "binder.h"
#include "bound_statement.hpp"
#include "catalog.hpp"
#include "create_statement.hpp"
#include "logical_type.hpp"
#include "nodes/nodes.hpp"
#include "nodes/pg_list.hpp"
#include "nodes/primnodes.hpp"
#include "pg_definitions.hpp"
#include "postgres_parser.hpp"
#include "spdlog/fmt/bundled/core.h"
#include <cstdio>
#include <string>

namespace DaseX {

auto Binder::BindColumnDefinition(duckdb_libpgquery::PGColumnDef *cdef)
    -> Field {
  std::string col_name;
  if (cdef->colname != nullptr) {
    col_name = cdef->colname;
  }

  auto type_name = std::string((reinterpret_cast<duckdb_libpgquery::PGValue *>(
                                    cdef->typeName->names->tail->data.ptr_value)
                                    ->val.str));

  if (type_name == "int4") {
    return {col_name, LogicalType::INTEGER};
  }

  if (type_name == "double") {
    return {col_name, LogicalType::DOUBLE};
  }

  // bool?

  if (type_name == "varchar") {
    //
    return {col_name, LogicalType::STRING};
  }
}

auto Binder::BindCreate(duckdb_libpgquery::PGCreateStmt *pg_stmt)
    -> std::unique_ptr<CreateStatement> {
  auto table = std::string(pg_stmt->relation->relname);
  auto columns = std::vector<Field>();
  size_t column_count = 0;
  std::vector<std::string> primary_key;

  for (auto cell = pg_stmt->tableElts->head; cell != nullptr;
       cell = lnext(cell)) {
    auto node =
        reinterpret_cast<duckdb_libpgquery::PGNode *>(cell->data.ptr_value);
    switch (node->type) {
    case duckdb_libpgquery::T_PGColumnDef: {
      auto cdef = reinterpret_cast<duckdb_libpgquery::PGColumnDef *>(
          cell->data.ptr_value);
      auto centry = BindColumnDefinition(cdef);
      // TODO: 处理对列有限制的时候

      columns.emplace_back(std::move(centry));
      column_count++;
      break;
    }
    }
  }

  if (column_count == 0) {
    printf("at least 1 column!\n");
  }
  return std::make_unique<CreateStatement>(std::move(table), std::move(columns),
                                           std::move(primary_key));
}

} // namespace DaseX